#include "fastcgi/soduku.h"
#include "fastcgi/fastcgi.h"
#include "../server/base/Utils.h"
#include "../server/logging/Logging.h"
#include "../server/net/EventLoop.h"
#include "../server/net/TcpServer.h"
#include "http/HttpResponse.h"
#include "http/HttpServer.h"
#include <lua.hpp>
using namespace yhaida;
const std::string kPath = "/sudoku/";

void onRequest(const TcpConnectionPtr &conn,
               FastCgiCodec::ParamMap &params,
               Buffer *in) //&_stdin
{
    std::string uri = params["REQUEST_URI"];
    LOG_INFO << conn->name() << ": " << uri;

    // for (FastCgiCodec::ParamMap::const_iterator it = params.begin(); it != params.end(); ++it)
    // {
    //     LOG_DEBUG << it->first << " = " << it->second;
    // }
    // if (in->readableBytes() > 0)
    // {
    //     LOG_DEBUG << "stdin " << in->retrieveAllAsString();
    // }

    std::string result;
    if (uri.size() == kPath.size() + kCells && uri.find(kPath) == 0)
    {
        result = solveSudoku(uri.substr(kPath.size()));
    }
    else
    {
        result = "bad request";
    }
    
    const std::shared_ptr<FastCgiCodec> &codec = boost::any_cast<const std::shared_ptr<FastCgiCodec> &>(conn->getContext());
    HttpResponse response(codec->getKeepConn());
    response.setStatusCode(HttpResponse::k200Ok);
    response.setStatusQuery("OK");
    response.setContentType("text/html");
    if (result.size()!=81)
        return;
    // std::string nowTime = Timestamp::now().toFormattedString();
    std::string text = readFile("../html/shudu_response.html");
    //替换html
    int pos = 0;
    for (int i = 1; i <= 81; ++i)
    {
        pos = text.find("$" + std::to_string(i), pos);
        text.replace(pos, 2, result, i - 1, 1);
    }

    response.setBody(text);

    Buffer buffer;
    response.appendToBuffer(&buffer);

    conn->send(&buffer);
    if (!response.closeConnection())
    {
        conn->shutdown();
    }
}

void onConnection2(const TcpConnectionPtr &conn)
{
    if (conn->connected())
    {
        typedef std::shared_ptr<FastCgiCodec> CodecPtr;
        CodecPtr codec(new FastCgiCodec(onRequest));
        conn->setContext(codec);
        conn->setMessageCallback(
            std::bind(&FastCgiCodec::onMessage, codec, _1, _2, _3));
        conn->setTcpNoDelay(true);
    }
}

int main(int argc, char *argv[])
{
    lua_State *lua = luaL_newstate();
    if (luaL_dofile(lua, "../config.lua"))
    {
        abort();
    }
    lua_getglobal(lua, "serverFastCGI_port");
    lua_getglobal(lua, "serverFastCGI_numberThread");
    int server_port = lua_tonumber(lua, -2);
    int server_numberThread = lua_tonumber(lua, -1);
    lua_pop(lua, 2);

    Logging::setLogLevel(Logging::TRACE);
    EventLoop loop;
    InetAddress addr2(server_port);
    TcpServer server2(&loop, addr2, TcpServer::kReusePort);
    server2.setConnectionCallback(onConnection2);
    if (server_numberThread > 1)
    {
        server2.setThreadNum(server_numberThread);
    }
    server2.start();
    loop.loop();
}
